using System;
using System.Collections.Generic;
using System.Text;

namespace NegBinary
{
    public static class Convert
    {
        public static long NegBinaryToLong(string psNegBinary)
        {
            int iLength = psNegBinary.Length;
            long lResult = 0;
            for (int i = 0; i < iLength; i++)
            {
                char cA = psNegBinary[iLength - i - 1];
                if (cA == '1')
                    lResult += System.Convert.ToInt64( Math.Pow(-2.0, (double)i));
            }
            return lResult;
        }

        public static string LongToNegBinary(long plValue,int piWidth)
        {
            string sBinary = RapidHDL.Conversion.LongToBinaryString(System.Math.Abs(plValue), piWidth);
            char[] caBinary = sBinary.ToCharArray();
            bool bOdd = false;
            bool bComplement = false;
            if (plValue < 0)
            {
                for (int i = sBinary.Length - 1; i >= 0; i--)
                {
                    if (bComplement)
                    {
                        if (sBinary[i] == '1')
                            caBinary[i] = '0';
                        else
                        {
                            caBinary[i] = '1';
                            if (bOdd)
                                bComplement = false;
                        }
                    }
                    else
                    {
                        if (caBinary[i] == '1' && !bOdd)
                            bComplement = true;
                    }
                    bOdd = !bOdd;
                }
            }
            else
            {
                for (int i = sBinary.Length - 1; i >= 0; i--)
                {
                    if (bComplement)
                    {
                        if (sBinary[i] == '1')
                        {
                            caBinary[i] = '0';
                        }
                        else
                        {
                            caBinary[i] = '1';
                            if (!bOdd)
                                bComplement = false;
                        }
                    }
                    else
                    {
                        if (caBinary[i] == '1' && bOdd)
                            bComplement = true;
                    }
                    bOdd = !bOdd;
                }
            }
            string sResult = new string(caBinary);
            if (NegBinaryToLong(sResult) != plValue)
                throw new Exception("Neg Binary Conversion Failed");
            return sResult;
        }

    }
}
